//
//  STDRenderer.m
//  STDRenderSDK
//
//  Created by 陈学明 on 2023/3/14.
//

#import "STDSRenderer.h"
#import "STDIOSToCPPFuncs.h"
#import "STDIOSProvider.h"

const struct STDRenderEngineProvider global_engineProvider = {gl_getImageData_func, gl_getFontPath_func};
@interface STDSRenderer ()
@property (nonatomic, assign) void *engineHander;
@property (nonatomic, assign) int autoIncrementLayerId;
@property (nonatomic, strong) NSMutableDictionary<NSNumber*, STDSGLParam *>*layers;
@property (nonatomic, strong) STDSGLParam *selectedLayer;
@property (nonatomic, strong) STDSGLParam *currentComposeLayer;// 当前合成
@end

@implementation STDSRenderer

- (instancetype)init {
    self = [super init];
    if (self) {
        _autoIncrementLayerId = 100;
        _layers = [NSMutableDictionary dictionary];
        _duration = 5.0;
        _engineHander = NULL;
        _selectedLayer = nil;
        [self createRenderEngine];
    }
    return self;
}

- (void)testGL {
    stds_gl_testGl(_engineHander);
}

- (void)setDuration:(CGFloat)duration {
    _duration = duration;
    stds_gl_setComposeDuration(_engineHander, _duration);
}

- (int)getNewLayerID {
    return _autoIncrementLayerId++;
}

- (void)createRenderEngine {
    _engineHander = stds_gl_createRenderEngine();
    stds_gl_registerProvider(_engineHander, &global_engineProvider);
    stds_gl_setComposeDuration(_engineHander, _duration);
}

- (void)destroyRenderEngine {
    stds_gl_destroyRenderEngine(_engineHander);
    _engineHander = NULL;
    [_layers removeAllObjects];
    _selectedLayer = nil;
    _autoIncrementLayerId = 100;
}

- (void)renderPrograss:(CGFloat)prograss {
    stds_gl_setCurrentPrograss(_engineHander, prograss);
    stds_gl_render(_engineHander);
}

- (void)readPixelOfPrograss:(CGFloat)prograss width:(int *)width height:(int *)height data:(unsigned char **)data {
    stds_gl_readPixel(_engineHander, width, height, data);
}

- (STDSGLImageParam *)addImageLayerWithImagePath:(NSString *)imagePath {
    STDSGLImageParam *param = [[STDSGLImageParam alloc] init];
    param.path = imagePath;
    param.layerID = [self getNewLayerID];
    param.startLife = 0;
    param.durationLife = self.duration;
    
    stds_gl_addLayer(_engineHander, param.layerID, (int)param.layerType);
    stds_gl_setLayerLife(_engineHander, param.layerID, param.startLife, param.durationLife);
    const char *path = [param.path cStringUsingEncoding:NSUTF8StringEncoding];
    stds_gl_replaceImageAsset(_engineHander, param.layerID, param.assetID, path);
    
    
    [_layers setObject:param forKey:@(param.layerID)];
    _selectedLayer = param;
    if (_currentComposeLayer) {
        stds_gl_moveLayerToCompose(_engineHander, _selectedLayer.layerID, _currentComposeLayer.layerID);
    }
    return param;
}

- (STDSGLImageParam *)addImageLayerWithTextureID:(unsigned int)textureID width:(CGFloat)width height:(CGFloat)height {
    STDSGLImageParam *param = [[STDSGLImageParam alloc] init];
    param.textureId = textureID;
    param.layerID = [self getNewLayerID];
    param.startLife = 0;
    param.durationLife = self.duration;
    param.width = width;
    param.height = height;
    
    stds_gl_addLayer(_engineHander, param.layerID, (int)param.layerType);
    stds_gl_setLayerLife(_engineHander, param.layerID, param.startLife, param.durationLife);
    stds_gl_replaceImageTex(_engineHander, param.layerID, param.assetID, textureID, width, height);
    
    [_layers setObject:param forKey:@(param.layerID)];
    _selectedLayer = param;
    if (_currentComposeLayer) {
        stds_gl_moveLayerToCompose(_engineHander, _selectedLayer.layerID, _currentComposeLayer.layerID);
    }
    return param;
}

- (STDSGLSolidParam *)addSolidLayerWithColorRed:(float)red green:(float)green blue:(float)blue {
    STDSGLSolidParam *param = [[STDSGLSolidParam alloc] init];
    param.r = red;
    param.g = green;
    param.b = blue;
    param.layerID = [self getNewLayerID];
    param.durationLife = self.duration;
    param.startLife = 0.0;
    stds_gl_addLayer(_engineHander, param.layerID, (int)param.layerType);
    stds_gl_setLayerLife(_engineHander, param.layerID, param.startLife, param.durationLife);
    stds_gl_setLayerSize(_engineHander, param.layerID, 1.0, 1.0);
    stds_gl_setSolidLayerColor(_engineHander, param.layerID, red, green, blue);
    [_layers setObject:param forKey:@(param.layerID)];
    _selectedLayer = param;
    if (_currentComposeLayer) {
        stds_gl_moveLayerToCompose(_engineHander, _selectedLayer.layerID, _currentComposeLayer.layerID);
    }
    return param;
}

- (void)moveLayerToCompose:(int)layerId composeID:(int)composeId {
    stds_gl_moveLayerToCompose(_engineHander, layerId, composeId);
}

- (STDSGLCompseParam *)addCompose {
    return [self addComposeLayerWithWidth:1.0 height:1.0];
}

- (STDSGLCompseParam *)addComposeLayerWithWidth:(CGFloat)width height:(CGFloat)height {
    STDSGLCompseParam *param = [[STDSGLCompseParam alloc] init];
    param.layerID = [self getNewLayerID];
    param.durationLife = self.duration;
    param.startLife = 0.0;
    stds_gl_addLayer(_engineHander, param.layerID, (int)param.layerType);
    stds_gl_setLayerLife(_engineHander, param.layerID, param.startLife, param.durationLife);
    stds_gl_setLayerSize(_engineHander, param.layerID, width, height);
    _currentComposeLayer = param;
    [_layers setObject:param forKey:@(param.layerID)];
    return param;
}

- (void)selectCompose:(int)composeId {
    _currentComposeLayer = _layers[@(composeId)];
    if (_currentComposeLayer.layerType != STDSLayerTypeCompose) {
        _currentComposeLayer = nil;
    }
}

- (void)selectLayer:(int)layerId {
    _selectedLayer = _layers[@(layerId)];
}

- (void)removeLayer:(int)layerId {
    _layers[@(layerId)] = nil;
    if (_selectedLayer.layerID == layerId) {
        _selectedLayer = nil;
    }
    stds_gl_removeLayer(_engineHander, layerId);
}

- (void)replaceParam:(STDSGLParam *)param {
    if ([param isKindOfClass:STDSGLImageParam.class]) {
        STDSGLImageParam *imageParam = (STDSGLImageParam *)param;
        if (imageParam.data != NULL) {
            stds_gl_replaceImageData(_engineHander, param.layerID, param.assetID, imageParam.data, imageParam.width, imageParam.height);
        } else if (imageParam.textureId != -1) {
            stds_gl_replaceImageTex(_engineHander, param.layerID, param.assetID, imageParam.textureId, imageParam.width, imageParam.height);
        } else {
            const char *path = [imageParam.path cStringUsingEncoding:NSUTF8StringEncoding];
            stds_gl_replaceImageAsset(_engineHander, param.layerID, param.assetID, path);
        }
        _layers[@(param.layerID)] = param;
    }
}

- (void)replaceLayerAssetImgPath:(NSString *)path {
    if (_selectedLayer) {
        STDSGLImageParam *imageParam = (STDSGLImageParam *)_selectedLayer;
        imageParam.path = path;
        const char *cPath = [path cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_replaceImageAsset(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, cPath);
    }
}

- (void)replaceLayerTextureID:(unsigned int)textureID width:(CGFloat)width height:(CGFloat)height {
    if (_selectedLayer) {
        STDSGLImageParam *imageParam = (STDSGLImageParam *)_selectedLayer;
        imageParam.textureId = textureID;
        imageParam.width = width;
        imageParam.height = height;
        stds_gl_replaceImageTex(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, textureID, width, height);
    }
}

- (void)replaceLayerData:(unsigned char *)data width:(CGFloat)width height:(CGFloat)height {
    if (_selectedLayer) {
        STDSGLImageParam *imageParam = (STDSGLImageParam *)_selectedLayer;
        imageParam.textureId = 0;
        imageParam.width = width;
        imageParam.data = data;
        imageParam.height = height;
        stds_gl_replaceImageData(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, data, width, height);
    }
}

- (void)replaceLayerMaskTextureID:(unsigned int)textureID width:(CGFloat)width height:(CGFloat)height {
    if (_selectedLayer) {
        stds_gl_replaceMaskTex(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, textureID, width, height);
    }
}

- (void)replaceLayerMaskPath:(NSString *)path {
    if (_selectedLayer) {
        const char *cpath = [path cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_replaceMaskAsset(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, cpath);
    }
}

- (void)replaceLayerMaskData:(unsigned char *)data width:(CGFloat)width height:(CGFloat)height {
    if (_selectedLayer) {
        stds_gl_replaceMaskData(_engineHander, _selectedLayer.layerID, _selectedLayer.assetID, data, width, height);
    }
}

- (void)setComposeSizeSRC:(CGSize)size {
    stds_gl_setComposeSizeSRC(_engineHander, size.width, size.height);
}

- (void)addEffectType:(STDSEffectType)effectType {
    if (_selectedLayer) {
        stds_gl_addEffect(_engineHander, _selectedLayer.layerID, (int)effectType);
    }
}

- (void)removeEffect:(STDSEffectType)effectType {
    if (_selectedLayer) {
        stds_gl_removeEffect(_engineHander, _selectedLayer.layerID, (int)effectType);
    }
}

- (void)setBlend:(STDSBlendType)blendType {
    if (_selectedLayer) {
        _selectedLayer.blendType = blendType;
        stds_gl_setLayerBlend(_engineHander, _selectedLayer.layerID, (int)blendType);
    }
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name floatValue:(float *)floatValue count:(int)n {
    if (_selectedLayer) {
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeEffectFloatValue(_engineHander, _selectedLayer.layerID, (int)effectType, cname, floatValue, n);
    }
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name floatValue:(float)floatValue {
    float arr[1] = {floatValue};
    [self changeEffectArguments:effectType name:name floatValue:arr count:1];
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name intValue:(int *)intValue count:(int)n {
    if (_selectedLayer) {
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeEffectIntValue(_engineHander, _selectedLayer.layerID, (int)effectType, cname, intValue, n);
    }
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name intValue:(int)intValue {
    int arr[1] = {intValue};
    [self changeEffectArguments:effectType name:name intValue:arr count:1];
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name stringValue:(NSString *)stringValue {
    if (_selectedLayer) {
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cStrValue = [stringValue cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeEffectStringValue(_engineHander, _selectedLayer.layerID, (int)effectType, cname, cStrValue);
    }
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name data:(const char *)data width:(int)width height:(int)height {
    if (_selectedLayer) {
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeEffectBitmap(_engineHander, _selectedLayer.layerID, (int)effectType, cname, data, width, height);
    }
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name image:(UIImage *)image {
    
}

- (void)changeEffectArguments:(STDSEffectType)effectType name:(NSString *)name textureID:(unsigned int)textureID width:(int)width height:(int)height {
    if (_selectedLayer) {
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeEffectTex(_engineHander, _selectedLayer.layerID, (int)effectType, cname, textureID, width, height);
    }
}

/// 显示/隐藏效果
- (void)setVisibleOfEffect:(STDSEffectType)effectType visible:(BOOL)isVisible {
    if (_selectedLayer) {
        stds_gl_visibleEffect(_engineHander, _selectedLayer.layerID, (int)effectType, isVisible);
    }
}

- (BOOL)checkerStatus:(STDSEffectType)effectType label:(NSString *)label {
    if (_selectedLayer) {
        const char *clabel = [label cStringUsingEncoding:NSUTF8StringEncoding];
        return stds_gl_checkEffectStatus(_engineHander, _selectedLayer.layerID, (int)effectType, clabel);
    }
    return NO;
}

/// 添加热加载效果
- (void)addHotEffect:(NSString *)effectName path:(NSString *)path {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *pathcname = [path cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_addHotEffect(_engineHander, _selectedLayer.layerID, effectcname, pathcname);
    }
}

/// 移除热加载效果
- (void)removeHotEffect:(NSString *)effectName {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_removeHotEffect(_engineHander, _selectedLayer.layerID, effectcname);
    }
}

/// 设置热加载效果参数
- (void)changeHotEffectArguments:(NSString *)effectName name:(NSString *)name floatValue:(float *)floatValue count:(int)n {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotEffectFloatValue(_engineHander, _selectedLayer.layerID, effectcname, cname, floatValue, n);
    }
}

- (void)changeHotEffectArguments:(NSString *)effectName name:(NSString *)name floatValue:(float)floatValue {
    float arr[1] = {floatValue};
    [self changeHotEffectArguments:effectName name:name floatValue:arr count:1];
}

- (void)changeHotEffectArguments:(NSString *)effectName name:(NSString *)name intValue:(int *)intValue count:(int)n {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotEffectIntValue(_engineHander, _selectedLayer.layerID, effectcname, cname, intValue, n);
    }
}

- (void)changeHotEffectArguments:(NSString *)effectName name:(NSString *)name intValue:(int)intValue {
    int arr[1] = {intValue};
    [self changeHotEffectArguments:effectName name:name intValue:arr count:1];
}

- (void)changeHotEffectArguments:(NSString *)effectName name:(NSString *)name stringValue:(NSString *)stringValue {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cname = [name cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cStrValue = [stringValue cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotEffectStringValue(_engineHander, _selectedLayer.layerID, effectcname, cname, cStrValue);
    }
}

/// 显示/隐藏热加载效果
- (void)setVisibleOfHotEffect:(NSString *)effectName visible:(BOOL)isVisible {
    if (_selectedLayer) {
        const char *effectcname = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_visibleHotEffect(_engineHander, _selectedLayer.layerID, effectcname, isVisible);
    }
}

- (void)addHotFilter:(NSString *)filterName path:(NSString *)path {
    if (_selectedLayer) {
        const char *cfilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cpath = [path cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_addHotFilter(_engineHander, _selectedLayer.layerID, cfilter, cpath);
    }
}
/// 移除热加载效果
- (void)removeHotFilter:(NSString *)filterName {
    if (_selectedLayer) {
        const char *cFilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_removeHotFilter(_engineHander, _selectedLayer.layerID, cFilter);
    }
}

- (void)changeHotFilterArguments:(NSString *)filterName effectName:(NSString *)effectName name:(NSString *)name floatValue:(float *)floatValue count:(int)n {
    if (_selectedLayer) {
        const char *cFilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cEffect = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cName = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotFilterFloatValue(_engineHander, _selectedLayer.layerID, cFilter, cEffect, cName, floatValue, n);
    }
}

- (void)changeHotFilterArguments:(NSString *)filterName effectName:(NSString *)effectName name:(NSString *)name floatValue:(float)floatValue {
    float arr[1] = {floatValue};
    [self changeHotFilterArguments:filterName effectName:effectName name:name floatValue:arr count:1];
}

- (void)changeHotFilterArguments:(NSString *)filterName effectName:(NSString *)effectName name:(NSString *)name intValue:(int *)intValue count:(int)n {
    if (_selectedLayer) {
        const char *cFilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cEffect = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cName = [name cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotFilterIntValue(_engineHander, _selectedLayer.layerID, cFilter, cEffect, cName, intValue, n);
    }
}

- (void)changeHotFilterArguments:(NSString *)filterName effectName:(NSString *)effectName name:(NSString *)name intValue:(int)intValue {
    int arr[1] = {intValue};
    [self changeHotFilterArguments:filterName effectName:effectName name:name intValue:arr count:1];
}

- (void)changeHotFilterArguments:(NSString *)filterName effectName:(NSString *)effectName name:(NSString *)name stringValue:(NSString *)stringValue {
    if (_selectedLayer) {
        const char *cFilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cEffectName = [effectName cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cName = [name cStringUsingEncoding:NSUTF8StringEncoding];
        const char *cStrValue = [stringValue cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_changeHotFilterStringValue(_engineHander, _selectedLayer.layerID, cFilter, cEffectName, cName, cStrValue);
    }
}

/// 显示/隐藏热加载效果
- (void)setVisibleOfHotFilter:(NSString *)filterName visible:(BOOL)isVisible {
    if (_selectedLayer) {
        const char *cFilter = [filterName cStringUsingEncoding:NSUTF8StringEncoding];
        stds_gl_visibleHotFilter(_engineHander, _selectedLayer.layerID, cFilter, isVisible);
    }
}

- (void)dealloc {
    stds_gl_destroyRenderEngine(_engineHander);
    _engineHander = NULL;
    NSLog(@"dealloc--STDSRenderer");
}

- (void)setLayerVisible:(BOOL)isVisible {
    if (_selectedLayer) {
        _selectedLayer.isVisible = isVisible;
        stds_gl_visibleLayer(_engineHander, _selectedLayer.layerID, isVisible);
    }
}

/// 将图层移动到最上面
- (void)moveLayerToTop {
    if (_selectedLayer) {
        stds_gl_moveLayerToTop(_engineHander, _currentComposeLayer ? _currentComposeLayer.layerID : 0, _selectedLayer.layerID);
    }
}

/// 将图层移动到最下面
- (void)moveLayerToBottom {
    if (_selectedLayer) {
        stds_gl_moveLayerToBottom(_engineHander, _currentComposeLayer ? _currentComposeLayer.layerID : 0, _selectedLayer.layerID);
    }
}

/// 移动到 targetLayerID 图层之上
- (void)moveLayerToFront:(int)targetLayerID {
    if (_selectedLayer) {
        stds_gl_moveLayerToFront(_engineHander, _currentComposeLayer ? _currentComposeLayer.layerID : 0, _selectedLayer.layerID, targetLayerID);
    }
}

/// 移动到 targetLayerID 图层之下
- (void)moveLayerToBack:(int)targetLayerID {
    if (_selectedLayer) {
        stds_gl_moveLayerToBack(_engineHander, _currentComposeLayer ? _currentComposeLayer.layerID : 0, _selectedLayer.layerID, targetLayerID);
    }
}

/// 设置图层大小
- (void)setLayerSize:(CGSize)size {
    if (_selectedLayer) {
        stds_gl_setLayerSize(_engineHander, _selectedLayer.layerID, size.width, size.height);
    }
}

/// 设置图层中心点位置
- (void)setLayerCenter:(CGPoint)center {
    if (_selectedLayer) {
        _selectedLayer.center = center;
        stds_gl_setLayerCenter(_engineHander, _selectedLayer.layerID, center.x, center.y);
    }
}

/// 设置图层旋转
- (void)setLayerRotate:(CGFloat)rotate {
    if (_selectedLayer) {
        _selectedLayer.rotate = rotate;
        stds_gl_setLayerRotate(_engineHander, _selectedLayer.layerID, rotate);
    }
}

/// 设置图层缩放比例
- (void)setLayerScale:(CGSize)scale {
    if (_selectedLayer) {
        _selectedLayer.scale = scale;
        stds_gl_setLayerScale(_engineHander, _selectedLayer.layerID, scale.width, scale.height);
    }
}

/// 设置图层透明度
- (void)setLayerAlpha:(CGFloat)alpha {
    if (_selectedLayer) {
        _selectedLayer.alpha = alpha;
        stds_gl_setLayerAlpha(_engineHander, _selectedLayer.layerID, alpha);
    }
}

/// 平移
- (void)translationLayer:(CGVector)distence {
    if (_selectedLayer) {
        stds_gl_transformation_translationLayer(_engineHander, _selectedLayer.layerID, distence.dx, distence.dy);
    }
}

/// 旋转
- (void)rotationLayer:(CGFloat)rotation {
    if (_selectedLayer) {
        stds_gl_transformation_rotationLayer(_engineHander, _selectedLayer.layerID, rotation);
    }
}

/// 缩放
- (void)scaleLayer:(CGVector)scale {
    if (_selectedLayer) {
        stds_gl_transformation_scaleLayer(_engineHander, _selectedLayer.layerID, scale.dx, scale.dy);
    }
}
@end
